package com.blast.manager.blast

import android.content.Intent
import android.text.TextUtils
import android.view.KeyEvent
import android.view.View
import com.blast.manager.R
import com.blast.manager.bean.ReadyErrorModel
import com.blast.manager.blast.presenter.BlastChargeReadyPresenter
import com.blast.manager.blast.presenter.BlastCountDownPresenter
import com.blast.manager.blast.presenter.BlastReadyPresenter
import com.blast.manager.blast.presenter.BlastSerialPresenter
import com.blast.manager.net.presenter.*
import com.blast.manager.net.ui.DetonatorListActivity
import com.blast.manager.net.ui.NotMatchActivity
import com.wxl.common.AppContext
import com.wxl.common.base.AbsActivity
import com.wxl.common.event.LookBlastLogEvent
import com.wxl.common.life.ViewModelQuick
import com.wxl.common.room.entity.BlastRecordEntity
import com.wxl.common.room.entity.LeiGuanDelayEntity
import com.wxl.common.room.entity.LeiGuanEntity
import com.wxl.common.room.entity.LogEntity
import com.wxl.common.room.helper.DBHelper
import com.wxl.common.util.ObservableUtil
import com.wxl.common.util.Toll
import com.wxl.common.wiget.ProgressUpdatePop
import com.wxl.common.wiget.WarnPop
import io.reactivex.ObservableOnSubscribe
import io.reactivex.functions.Action
import kotlinx.android.synthetic.main.activity_blast_layout.*
import org.greenrobot.eventbus.EventBus

class BlastActivity : AbsActivity() {

    var isDelayPlan = false
    var voltage = "0"
    var electric = "0"
    var clickTime = 0L
    var clickLongTime1 = 0L
    var clickLongTime2 = 0L
    var isReadEnd = false
    var isCountDown10s = false
    var isCountDown60s = true

    override fun getCreateContentViewId(): Int {
        return R.layout.activity_blast_layout
    }

    override fun onCreateViewChanged() {
        isCheckAppUpgrade = false
        setTopTitle("起爆控制")

        isReadEnd = false

        isDelayPlan = intent.getBooleanExtra("delay", false)
        if (intent.hasExtra("voltage")) {
            voltage = intent.getStringExtra("voltage").toString()
        }
        if (intent.hasExtra("electric")) {
            electric = intent.getStringExtra("electric").toString()
        }

        ViewModelQuick.observer(this, BlastSerialPresenter::class.java, this)
        ViewModelQuick.observer(this, NetCheckPortPresenter::class.java, this)
        ViewModelQuick.observer(
            this,
            NetCheckChargePresenter::class.java,
            voltageText,
            electricText
        )

        setOnClickEvent()

        observer(BlastReadyPresenter::class.java)
        observer(NetCheckNumberPresenter::class.java)
        observer(NetCheckReadyPresenter::class.java)
        observer(NetCheckErrorPresenter::class.java)
        observer(BlastChargeReadyPresenter::class.java)
        observer(BlastCountDownPresenter::class.java)
        show(BlastReadyPresenter::class.java)
    }

    private fun <P : AbsNetCheckPresenter> observer(cls: Class<P>) {
        ViewModelQuick.observer(this, cls, blastParentLayout)
    }

    fun getTotal(): Int {
        return ViewModelQuick.get(this, NetCheckReadyPresenter::class.java).getTotal()
    }


    fun getVoltage(): Double {
        return ViewModelQuick.get(this, NetCheckChargePresenter::class.java).getVoltage()
    }


    fun getElectric(): Double {
        return ViewModelQuick.get(this, NetCheckChargePresenter::class.java).getElectric()
    }

    fun addLog(action: String, p: Int, remark: String) {
        LogEntity.addLog(
            action,
            "",
            "起爆控制",
            getTotal(),
            getElectric(),
            getVoltage(),
            "",
            p,
            0,
            "",
            remark
        )
    }

    fun addLog(action: String, p: Int, code: String, remark: String) {
        LogEntity.addLog(
            action,
            code,
            "起爆控制",
            getTotal(),
            getElectric(),
            getVoltage(),
            "",
            p,
            0,
            "",
            remark
        )
    }

    fun addLog(action: String, p: Int, code: String, stateCode: String, remark: String) {
        LogEntity.addLog(
            action,
            code,
            "起爆控制",
            getTotal(),
            getElectric(),
            getVoltage(),
            stateCode,
            p,
            0,
            "",
            remark
        )
    }

    fun <P : AbsNetCheckPresenter> show(cls: Class<P>, vararg args: Any) {
        ViewModelQuick.get(this, cls).show(*args)
    }

    fun showText(text: String) {
        show(NetCheckNumberPresenter::class.java, text)
        showOnlyBack()
    }

    fun showTextGone(text: String) {
        show(NetCheckNumberPresenter::class.java, text)
        dismissButtonLayout()
    }

    fun dismissButtonLayout() {
        blastCheckBtnLayout.visibility = View.GONE
    }

    /**
     * 显示全部按钮
     */
    fun showButtonLayout() {
        isReadEnd = false
        blastCheckBtnLayout.visibility = View.VISIBLE
        blastCheckBackBtn.visibility = View.VISIBLE
        blastCheckChargeBtn1.visibility = View.VISIBLE
        blastCheckChargeBtn2.visibility = View.VISIBLE
        blastCheckLookBtn.visibility = View.VISIBLE
    }

    /**
     * 显示充电起爆提示
     */
    fun showChargeReadyLayout() {
        showButtonLayout()
        show(BlastChargeReadyPresenter::class.java)
    }

    fun showOnlyBack() {
        blastCheckBtnLayout.visibility = View.VISIBLE
        blastCheckBackBtn.visibility = View.VISIBLE
        blastCheckChargeBtn1.visibility = View.INVISIBLE
        blastCheckChargeBtn2.visibility = View.INVISIBLE
        blastCheckLookBtn.visibility = View.INVISIBLE
    }


    /**
     * 显示起爆按钮
     */
    fun showBlastButton() {
        showButtonLayout()
        isReadEnd = true
        isCountDown10s = true
        blastCheckLookBtn.visibility = View.INVISIBLE
        blastCheckChargeBtn1.text = "起爆"
        blastCheckChargeBtn2.text = "起爆"
    }

    /**
     * 起爆充电准备完毕
     */
    private fun showBlastReadEnd() {
        showButtonLayout()
        isReadEnd = true
        isCountDown10s = false
        isCountDown60s = true
        //blastCheckBackBtn.visibility = View.INVISIBLE
        blastCheckLookBtn.visibility = View.INVISIBLE
        val testModel = AppContext.appContext.getTestModel()
        if (testModel == 0) {
            blastCheckChargeBtn1.text = "起爆"
            blastCheckChargeBtn2.text = "起爆"
        } else if (testModel == 1) {
            blastCheckChargeBtn1.text = "准备起爆"
            blastCheckChargeBtn2.text = "准备起爆"
        } else {
            blastCheckChargeBtn1.text = "长按3s起爆"
            blastCheckChargeBtn2.text = "长按3s起爆"
        }
    }

    override fun onKeyDownEvent(keyCode: Int, event: KeyEvent?): Boolean {
        ViewModelQuick.get(this, NetCheckErrorPresenter::class.java).onKeyDownEvent(keyCode, event)
        ViewModelQuick.get(this, BlastReadyPresenter::class.java).onKeyDownEvent(keyCode, event)

        if (keyCode == KeyEvent.KEYCODE_F1) {
            blastCheckBackBtn.performClick()
        }
        if (keyCode == KeyEvent.KEYCODE_F2) {
            if (AppContext.appContext.getTestModel() == 0 || AppContext.appContext.getTestModel() == 1 || !isReadEnd && event!!.getRepeatCount() == 0) {
                blastCheckChargeBtn1.performClick()
            } else {
                blastCheckChargeBtn1.performLongClick()
            }
        }
        if (keyCode == KeyEvent.KEYCODE_F3) {
            if (AppContext.appContext.getTestModel() == 0 || AppContext.appContext.getTestModel() == 1 || !isReadEnd && event!!.getRepeatCount() == 0) {
                blastCheckChargeBtn2.performClick()
            } else {
                blastCheckChargeBtn2.performLongClick()
            }
        }
        if (keyCode == KeyEvent.KEYCODE_F4) {
            blastCheckLookBtn.performClick()
        }
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            blastCheckBackBtn.performClick()
        }

        return true
    }

    override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
        if (keyCode == KeyEvent.KEYCODE_F3 || keyCode == KeyEvent.KEYCODE_F4) {
            if (!isCountDown60s && AppContext.appContext.getTestModel() == 2) {
                onLongClickEventUp()
            }
        }
        return super.onKeyUp(keyCode, event)
    }


    /**
     * 显示警告
     */
    fun showWarn() {
        ViewModelQuick.get(this, BlastCountDownPresenter::class.java)
            .stopCountDown()
        WarnPop.show(this, "终止起爆，\n" +
                "雷管已充入高压，\n" +
                "请按爆破规程要求处理现场！", Action {
            dismissClearAllPop()
            ViewModelQuick.get(this, BlastSerialPresenter::class.java)
                .closeElectric(object :
                    ObservableUtil.Companion.OnNextCallback<Boolean>() {
                    override fun onNext(t: Boolean) {
                        if (t) {
                            finish()
                        } else {
                            Toll.toll("关电失败。")
                            blastCheckBackBtn.performClick()
                        }
                    }
                })
        }, Action {

            dismissClearAllPop()

            if (AppContext.appContext.getTestModel() == 0) {
                if (isCountDown60s) {//倒计时60s
                    ViewModelQuick.get(this, BlastCountDownPresenter::class.java).restartCountDown()
                } else {
                    ViewModelQuick.get(this, BlastCountDownPresenter::class.java).blastNormalModel()
                }
            } else {
                isCountDown10s = false
                isCountDown60s = true
                ViewModelQuick.get(this, BlastCountDownPresenter::class.java).restartCountDown()
                if(AppContext.appContext.getTestModel() == 1){
                    showBlastReadEnd()
                }
            }

        })
    }


    private fun setOnClickEvent() {
        blastCheckBackBtn.setOnClickListener {
            if (blastCheckBackBtn.isShown) {
                if (isReadEnd) {
                    showWarn()
                } else {
                    finish()
                }
            }
        }
        blastCheckChargeBtn1.setOnClickListener {
            if (blastCheckChargeBtn1.isShown) {
                checkDoubleClick()
            }
        }
        blastCheckChargeBtn2.setOnClickListener {
            if (blastCheckChargeBtn2.isShown) {
                checkDoubleClick()
            }
        }
        blastCheckLookBtn.setOnClickListener {
            if (blastCheckLookBtn.isShown) {
                checkDelayCollector()
            }
        }


        if (AppContext.appContext.getTestModel() == 2) {
            blastCheckChargeBtn1.setOnLongClickListener(object : View.OnLongClickListener {
                override fun onLongClick(v: View?): Boolean {
                    if (blastCheckChargeBtn1.isShown) {
                        clickLongTime1 = System.currentTimeMillis()
                        if (clickLongTime2 != 0L) {
                            onLongClickBlast()
                        }
                    }
                    return true
                }
            })

            blastCheckChargeBtn2.setOnLongClickListener(object : View.OnLongClickListener {
                override fun onLongClick(v: View?): Boolean {
                    if (blastCheckChargeBtn2.isShown) {
                        clickLongTime2 = System.currentTimeMillis()
                        if (clickLongTime1 != 0L) {
                            onLongClickBlast()
                        }
                    }
                    return true
                }
            })
        }
    }


    /**
     * 取消长按
     */
    private fun onLongClickEventUp() {
        clickLongTime2 = 0
        clickLongTime1 = 0
        isCountDown60s = true
        ViewModelQuick.get(this, BlastCountDownPresenter::class.java).restartCountDown()
    }


    /**
     * 长按起爆
     */
    private fun onLongClickBlast() {
        if (isCountDown60s) {
            isCountDown60s = false
            ViewModelQuick.get(this, BlastCountDownPresenter::class.java).startBlast()
        }
    }

    private fun checkDelayCollector() {
        DBHelper.queryLeiGuanEntity(object :
            ObservableUtil.Companion.OnNextCallback<List<LeiGuanEntity>>() {
            override fun onNext(t: List<LeiGuanEntity>) {
                DBHelper.queryLeiGuanDelayEntity(object :
                    ObservableUtil.Companion.OnNextCallback<List<LeiGuanDelayEntity>>() {
                    override fun onNext(delayData: List<LeiGuanDelayEntity>) {
                        ObservableUtil.doNext(
                            ObservableOnSubscribe {
                                delayData.forEach { dd ->
                                    t.forEach {
                                        if (TextUtils.equals(dd.UID, it.UID)) {
                                            dd.collectorNumber = it.collectorNumber
                                        }
                                    }
                                }
                                it.onNext(delayData)
                            },
                            object :
                                ObservableUtil.Companion.OnNextCallback<List<LeiGuanDelayEntity>>() {
                                override fun onNext(t: List<LeiGuanDelayEntity>) {
                                    if (t.isEmpty()) {
                                        Toll.toll("没有雷管数据。")
                                    } else {
                                        AppContext.appContext.setLeiGuanDelayEntity("blastDelayData",t as ArrayList<LeiGuanDelayEntity>)
                                        val intent = Intent(
                                            this@BlastActivity,
                                            DetonatorListActivity::class.java
                                        )
                                        intent.putExtra("key", "blastDelayData")
                                        startActivity(intent)
                                    }
                                }
                            })
                    }
                })
            }
        })
    }

    @Synchronized
    private fun checkDoubleClick() {
        if (System.currentTimeMillis() - clickTime < 500) {
            clickTime = 0L
            if (isReadEnd) {
                toBlast()
                return
            }
            addLog("充电起爆", 0, "点击充电起爆")
            ProgressUpdatePop.show(this)
            ViewModelQuick.get(this, BlastSerialPresenter::class.java)
                .charge(object : BlastSerialPresenter.OnChargeCallback {
                    override fun onChargeResult() {
                        addLog("充电起爆", 100, "充电起爆成功")
                        ProgressUpdatePop.updateProgress(-1, "充电完成...", "雷管充电", 100)
                        show(BlastCountDownPresenter::class.java)
                        showBlastReadEnd()
                    }

                    override fun onChargeProgress(p: Int, sub: String, max: Int) {
                        //addLog("充电起爆", p, sub)
                        ProgressUpdatePop.updateProgress(p, sub, "雷管充电", max)
                    }

                    override fun onVoltageElectricChanged(mVoltage: Int, mElectric: Int) {
                        ViewModelQuick.get(
                            this@BlastActivity,
                            NetCheckChargePresenter::class.java
                        )
                            .onChargeElectricChanged(mVoltage, mElectric)
                    }

                    override fun onChargeProgressError(sub: String) {
                        addLog("充电起爆", 100, sub)
                        ProgressUpdatePop.updateProgress(-1, sub, "雷管充电", 100)
                        showText(sub)
                    }

                    override fun onChargeResultError(
                        error: List<ReadyErrorModel>,
                        notMatchArray: List<LeiGuanEntity>,
                        notAuthArray: List<LeiGuanEntity>,
                        notChargeArray: List<LeiGuanEntity>
                    ) {
                        ProgressUpdatePop.updateProgress(-1, "充电失败...", "雷管充电", 100)
                        ViewModelQuick.get(
                            this@BlastActivity,
                            NetCheckErrorPresenter::class.java
                        )
                            .showBlastError(error, notAuthArray, notMatchArray, notChargeArray)
                    }

                })
        } else {
            if (clickTime != 0L) {
                clickTime = 0L
                Toll.toll("同时按下充电起爆按钮")
            } else {
                clickTime = System.currentTimeMillis()
                blastCheckChargeBtn1.postDelayed(Runnable { clickTime = 0L }, 500)
            }
        }
    }


    /**
     * 开始爆破
     */
    private fun toBlast() {
        isCountDown60s = false
        if (AppContext.appContext.getTestModel() == 0) {
            showOnlyBack()
            ViewModelQuick.get(this, BlastCountDownPresenter::class.java).blast()
        } else {
            if (isCountDown10s) {
                showOnlyBack()
                ViewModelQuick.get(this, BlastCountDownPresenter::class.java).blast()
            } else {
                showBlastButton()
                ViewModelQuick.get(this, BlastCountDownPresenter::class.java).startTestModel1Blast()
            }
        }
    }

    /**
     * 显示爆破错误
     */
    fun showBlastErrorResult(blastError: List<LeiGuanEntity>) {
        isReadEnd = false
        showButtonLayout()
        blastCheckBackBtn.visibility = View.VISIBLE
        blastCheckLookBtn.visibility = View.VISIBLE
        blastCheckChargeBtn1.visibility = View.INVISIBLE
        blastCheckChargeBtn2.visibility = View.INVISIBLE
        blastCheckLookBtn.setOnClickListener {
            val intent = Intent(this, NotMatchActivity::class.java)
            intent.putExtra("data", blastError as ArrayList)
            intent.putExtra("isBlastError", true)
            startActivity(intent)
        }
    }

    /**
     * 显示爆破成功
     */
    fun showBlastResult(blast: List<BlastRecordEntity>) {
        isReadEnd = false
        showButtonLayout()
        blastCheckBackBtn.visibility = View.VISIBLE
        blastCheckLookBtn.visibility = View.VISIBLE
        blastCheckChargeBtn1.visibility = View.INVISIBLE
        blastCheckChargeBtn2.visibility = View.INVISIBLE
        val e = LookBlastLogEvent()
        EventBus.getDefault().post(e)
        finish()
    }

    override fun onDestroy() {
        if (isReadEnd) {//意外中断（发生短路时）
            ViewModelQuick.get(this, BlastSerialPresenter::class.java)
                .closeElectric(object :
                    ObservableUtil.Companion.OnNextCallback<Boolean>() {
                    override fun onNext(t: Boolean) {
                    }
                })
        }
        super.onDestroy()
    }
}